using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using GuavaData;

namespace GuavaLib
{
    public partial class SingleClassifierBuilder : Form
    {
        ClassifierWrapper cw;

        public ClassifierWrapper Classifier
        {
            get { return cw; }
            set { cw = value; }
        }
        
        public SingleClassifierBuilder(Column outColumn, List<Column> queryColumns, ClassifierWrapper cw)
        {
            InitializeComponent();

            foreach (Column c in queryColumns)
            {
                this.QueryColumns.Items.Add(c);
            }
            this.QueryColumns.DisplayMember = "Name";

            if (outColumn.dom.ListOutput() == null)
                OutputColumnDomain.Enabled = false;
            else
                foreach (object obj in outColumn.dom.ListOutput())
                    OutputColumnDomain.Items.Add(obj);

            // Add double-click handlers
            this.QueryColumns.DoubleClick += new EventHandler(QueryColumns_DoubleClick);
            this.QueryColumnDomain.DoubleClick += new EventHandler(QueryColumnDomain_DoubleClick);
            this.OutputColumnDomain.DoubleClick += new EventHandler(OutputColumnDomain_DoubleClick);

            this.cw = cw;
            this.txtClassifierCode.Text = this.Classifier.classifierCode;
            this.txtNotes.Text = this.Classifier.comments;
        }

        void OutputColumnDomain_DoubleClick(object sender, EventArgs e)
        {
            if (this.OutputColumnDomain.SelectedIndex >= 0) this.txtClassifierCode.AppendText(String.Concat("\"", this.OutputColumnDomain.SelectedItem.ToString(), "\""));
        }

        void QueryColumnDomain_DoubleClick(object sender, EventArgs e)
        {
            if (this.QueryColumnDomain.SelectedIndex >= 0) this.txtClassifierCode.AppendText(String.Concat("\"", this.QueryColumnDomain.SelectedItem.ToString(), "\""));
        }

        void QueryColumns_DoubleClick(object sender, EventArgs e)
        {
            if (this.QueryColumns.SelectedIndex >= 0)
            {
                Column cTemp = this.QueryColumns.SelectedItem as Column;
                this.txtClassifierCode.AppendText(String.Concat("[[", cTemp.Name, "]]"));
                if (!(Classifier.input.Contains(cTemp))) Classifier.input.Add(cTemp);
            }
        }

        private void QueryColumns_SelectedIndexChanged(object sender, EventArgs e)
        {
            Column c = QueryColumns.SelectedItem as Column;
            String str = c.Name;
            GuavaData.Domain.Domain dom = c.dom;

            // Fix the domain listed
            QueryColumnDomain.Items.Clear();
            if (dom.ListOutput() == null)
                QueryColumnDomain.Items.Add(dom);
            else
                foreach (object obj in dom.ListOutput())
                    QueryColumnDomain.Items.Add(obj);
        }

        private void btnAnd_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" AND");
        }

        private void btnOR_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" OR");
        }

        private void btnNOT_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" NOT");
        }

        private void btnLParen_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText("(");
        }

        private void btnRParen_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(")");
        }

        private void btnIfThen_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" ==>");
        }

        private void btnPlus_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" +");
        }

        private void btnMinus_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" -");
        }

        private void btnTimes_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" *");
        }

        private void btnDivide_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" /");
        }

        private void btnEquals_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" ==");
        }

        private void btnNotEquals_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" <>");
        }

        private void btnLess_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" <");
        }

        private void btnLessEqual_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" <=");
        }

        private void btnGreater_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" >");
        }

        private void btnGreaterEqual_Click(object sender, EventArgs e)
        {
            this.txtClassifierCode.AppendText(" >=");
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Classifier.classifierCode = this.txtClassifierCode.Text;

            // Validate that the "referenced" columns are still referenced
            List<Column> toKeep = new List<Column>();
            foreach (Column cTemp in Classifier.input)
            {
                string toFind = String.Concat("[", cTemp.Name, "]");
                if (this.txtClassifierCode.Text.Contains(toFind)) toKeep.Add(cTemp);
            }
            if (toKeep.Count <= 0)
            {
                MessageBox.Show("A classifier must refer to at least one input column.");
                return;
            }
            Classifier.input = toKeep;
            Classifier.comments = txtNotes.Text;

            this.Close();
        }

        private void btnValidate_Click(object sender, EventArgs e)
        {
            this.Classifier.classifierCode = this.txtClassifierCode.Text;

            // Validate that the "referenced" columns are still referenced
            List<Column> toKeep = new List<Column>();
            foreach (Column cTemp in Classifier.input)
            {
                string toFind = String.Concat("[", cTemp.Name, "]");
                if (this.txtClassifierCode.Text.Contains(toFind)) toKeep.Add(cTemp);
            }
            if (toKeep.Count <= 0)
            {
                MessageBox.Show("A classifier must refer to at least one input column.");
                return;
            }
            Classifier.input = toKeep;
            Classifier.comments = txtNotes.Text;

            if (GuavaData.Classifier.Build(Classifier) != null) MessageBox.Show("Classifier code will compile and run.");
        }
    }
}